// #![allow(dead_code)]
// #![allow(unused_variables)]
// #![allow(unused_imports)]

mod info;
mod logic;

use info::Info;
use js_sys::*;
use logic::{ExFun, Logic};
use serde_wasm_bindgen;
use wasm_bindgen::{prelude::*, JsValue};

#[wasm_bindgen(js_namespace = Math)]
extern "C" {
    fn random() -> f32;
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);

}

macro_rules! console_log {
    ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}

impl ExFun {
    fn random() -> f32 {
        random()
    }

    fn shuffle(res: &mut Vec<u32>) {
        for i in 0..res.len() {
            let j = ((i as f32) * Self::random()).floor() as usize;
            [res[i], res[j]] = [res[j], res[i]];
        }
    }

    fn log(info: &str) {
        console_log!("{}", info);
    }
}

#[wasm_bindgen]
pub fn create_new_info(line_str: String, client_second: f32) -> JsValue {
    serde_wasm_bindgen::to_value(&(Info::new(line_str, client_second))).unwrap()
}

#[wasm_bindgen]
pub struct RsCore {
    logic: Logic,
}

#[wasm_bindgen]
impl RsCore {
    #[wasm_bindgen(constructor)]
    pub fn new(info_js: JsValue) -> RsCore {
        let info = serde_wasm_bindgen::from_value(info_js).unwrap();
        RsCore {
            logic: Logic::new(info),
        }
    }

    pub fn reset(&mut self, str_pl: String, str_tl: String, str_s: String, str_el: String) {
        self.logic.reset(str_pl, str_tl, str_s, str_el);
    }

    pub fn step(&mut self, time: f32) {
        self.logic.step(time);
        self.logic.update_fish_state();
    }

    pub fn reap_fish(&mut self) -> bool {
        self.logic.reap_fish()
    }

    pub fn get_client_second(&self) -> f32 {
        return self.logic.info.base.client_second;
    }

    pub fn set_client_second(&mut self, client_second: f32) {
        self.logic.info.base.client_second = client_second;
    }

    pub fn cat_receive_money(&mut self, money: u32) {
        self.logic.cat_receive_money(money)
    }

    pub fn province_played_sids(&self) -> Vec<u32> {
        self.logic.cur_pid_played_sids()
    }

    pub fn get_info_rs(&self) -> JsValue {
        serde_wasm_bindgen::to_value(&self.logic.info).unwrap()
    }

    pub fn get_played_sids_by_pid(&self, pid: u32) -> Vec<u32> {
        self.logic.get_played_sids_by_pid(pid)
    }

    pub fn user_add_money(&mut self, money: u32) {
        self.logic.user_add_money(money)
    }

    pub fn user_sub_money(&mut self, money: u32) {
        self.logic.user_sub_money(money)
    }
}
